<!--
/**
* @author xuyh0817
* @email xuyh0817@foxmail.com
* @date 2022-02-22 01:23
* @version 2.0.0
* @doc todo
* @website todo
* @remark  如果要分发源码，需在本文件顶部保留此文件头信息！！
*/
-->
<template>
  <a-modal
      title="数据编辑"
      :visible="visible"
      :footer="null"
      centered
      width="90%"
      @cancel="$emit('update:visible',false)"
  >
    <a-alert
        message="数据必须为对象"
        type="warning"
        show-icon
        style="margin-bottom: 10px"
    />
    <PrismEditor
        v-model="code"
        class="x-render-code"
        :highlight="highlighter"
        line-numbers
    />
    <div style="text-align:center;margin-top: 20px;">
      <a-button type="primary" style="margin: 0 8px" @click="changeCodeHandler">更改数据</a-button>
      <a-button type="primary" style="margin: 0 8px" @click="copyDataHandler">复制数据</a-button>
      <a-button type="primary" style="margin: 0 8px" @click="downloadDataHandler">下载数据</a-button>
      <a-button @click="$emit('update:visible', false)">关闭弹窗</a-button>
    </div>
  </a-modal>
</template>

<script>
import {highlight, languages} from 'prismjs/components/prism-core'
import {cloneDeep, debounce, isPlainObject} from 'lodash'
import copy from 'clipboard-copy'
// 代码编辑器
import { PrismEditor } from "vue-prism-editor"
import 'prismjs/components/prism-clike'
import 'prismjs/components/prism-javascript'

export default {
  name: 'XRenderDataDialog',
  inject: ['xDesignForm'],
  components:{
    PrismEditor
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      code: '',
      fileURL: ''
    }
  },
  watch: {
    visible(val) {
      if (val) {
        this.code = this.reomveQuotes(this.xDesignForm.getFormConfigStr())
      }
    },
    code: {
      handler() {
        // 防抖，最后一次起作用
        if (!this.codeToURL) {
          this.codeToURL = debounce(() => {
            // 将代码转为 URL
            const blob = new Blob([this.code], {
              type: 'application/x-javascript'
            })
            this.fileURL = URL.createObjectURL(blob)
          }, 300)
        }
        this.codeToURL()
      },
      immediate: true
    }
  },
  methods: {
    /**
     * 移除双引号
     * @param {string} str
     * @example
     * reomveQuotes({"name": "zhang"}) => {name: "zhang"}
     */
    reomveQuotes(str) {
      return str.replace(/"(\w+)":/g, '$1:')
    },
    // 高亮配置
    highlighter(code) {
      return highlight(code, languages.js)
    },
    // 保存数据
    changeCodeHandler() {
      try {
        const {code, xDesignForm} = this
        // 将字符串转为对象
        const formConfig = (new Function('return ' + code))()
        // 判断是否为对象
        if (isPlainObject(formConfig)) {
          // 1. 通过解构符合的方式分离出 formDesc 和 formPropsData
          const {formProps, formOptions, formBtns} = cloneDeep(formConfig)
          // 2. 赋值 xDesignForm.formPropsData,formOptions,formBtns
          xDesignForm.formPropsData = Object.assign(xDesignForm.formPropsData, formProps)
          xDesignForm.formOptions.splice(0, xDesignForm.formOptions.length, ...formOptions)
          xDesignForm.formBtns.splice(0, xDesignForm.formBtns.length, ...formBtns)
        } else {
          // 抛出解析异常
          throw new TypeError('类型错误，非对象')
        }
      } catch (err) {
        // 错误提示
        this.$message.error('解析失败，非 JS 对象，请检查')
        console.error(err)
      }
    },
    // 复制数据
    copyDataHandler() {
      const {code} = this
      copy(code)
      this.$message.success('复制成功!')
    },
    downloadDataHandler() {
      const elink = document.createElement('a')
      elink.download = Date.now() + '.js'
      elink.style.display = 'none'
      elink.href = this.fileURL
      document.body.appendChild(elink)
      elink.click()
      // 释放URL 对象
      URL.revokeObjectURL(elink.href)
      document.body.removeChild(elink)
      this.$message.success('下载成功!')
    }
  }
}
</script>
<style lang="css" scoped>
.x-render-code {
  max-height: calc(80vh - 50px);
}
</style>
